/*
 * main.c
 *
 *  Created on: 27.11.2011
 *      Author: alexs
 */

#include "stm32f10x.h"
#include "stm32f10x_it.h"
#include "stm32f10x_conf.h"
//#include <stdio.h>
#include <stdlib.h>
#include "prn_func.h"
#include <string.h>
#include "main.h"
#include "rfm23.h"

#define LED_ON GPIO_ResetBits(GPIOA,GPIO_Pin_8)
#define LED_OFF GPIO_SetBits(GPIOA,GPIO_Pin_8)

const uint32_t arr26[]={CHIP26_0,CHIP26_1,CHIP26_2};
const uint32_t arr27[]={CHIP27_0,CHIP27_1,CHIP27_2};
uint32_t chip_SN[3];
uint8_t chip_tx=0;

char USART_TX_BUFF[USART_TX_BUFF_SIZE];
volatile uint8_t timeout_flag=0;
uint32_t psent=0;
uint32_t perr=0;

void HW_init();
uint8_t SPI_talk(SPI_dir dir, const uint8_t addr, const uint8_t val);

int main() {
	RCC_ClocksTypeDef clocks;
	uint8_t rndv=0;
	uint32_t * uid;
	uint8_t i,err;
	uint8_t darr[16];
	char * nextline;
	char nonext[]="";
	char tonext[]="\n";

//	volatile uint32_t a;
	//	uint8_t reg;

	HW_init();
//	LED_ON;
	RCC_GetClocksFreq(&clocks);

	DBGuld("Hi Alex! ",clocks.PCLK2_Frequency,"\r\n!!!\r\n");
//	a=0xfffff;
//	while (a--);

	uid=(uint32_t *)(0x1FFFF7E8);
	chip_SN[2]=*(uid++);
	chip_SN[1]=*(uid++);
	chip_SN[0]=*uid;

	if (memcmp(chip_SN,arr27,sizeof(chip_SN))==0) {
		DBGstr("Slave chip\r\n");
	}
	else if (memcmp(chip_SN,arr26,sizeof(chip_SN))==0) {
		DBGstr("Master chip\r\n");
		chip_tx=1;
	}
	else {
		DBGstr("Chip unknown!\r\n");
		DBGulh("SN2 0x",chip_SN[2],"\r\n");
		DBGulh("SN1 0x",chip_SN[1],"\r\n");
		DBGulh("SN0 0x",chip_SN[0],"\r\n");
	}
	TIM_Cmd(TIM4,ENABLE);
	while (!timeout_flag);
	timeout_flag=0;
	SPI_talk(WRITE,RFM23_07_Operating_Mode_and_Function_Control_1,0x80);
	TIM_Cmd(TIM4,ENABLE);
	while (!timeout_flag);
	timeout_flag=0;
	RFM23_Init(1);
	RFM23_to_READY();
	//	while (!RFM23_isready());

	for (;;){

		if (chip_tx) {
			RFM23_clear_tx();
			SPI_talk(WRITE,RFM23_3E_Packet_Length,16);
			for (i=0;i<16;i++) {
				darr[i]=rndv;
				RFM23_push(rndv);
				rndv++;
			}
//			DBGulh("Send 0x",rndv-1,"\r\n");
			RFM23_set_TXINT();
			RFM23_clear_intterrupt();
//			while (!NIRQ_stat());
			RFM23_to_TX();
			LED_ON;
			while (NIRQ_stat());
			RFM23_to_READY();
			LED_OFF;
			psent++;
			SPI_talk(WRITE,RFM23_7E_RX_FIFO_Control,21);
			RFM23_clear_rx();
			RFM23_to_RX();
			RFM23_set_RXINT();
			RFM23_clear_intterrupt();
			TIM_SetCounter(TIM4,0);
			timeout_flag=0;
			TIM_Cmd(TIM4,ENABLE);
			nextline=nonext;
			while ((NIRQ_stat())&&(!timeout_flag));
			TIM_Cmd(TIM4,DISABLE);
			if (NIRQ_stat()) {
				//ERROR
//				DBGstr("Error\r\n");
				perr++;
				nextline=tonext;
			}else{
				//OK
				err=0;
				for (i=0;i<21;i++) {
					if (i>4) {
						if (darr[i-5]!=RFM23_pop()) err=1;
					}else{
						RFM23_pop();
					}
				}
				if (!err) {
					//DBGstr("Ok\r\n");
				}else{
					//ERROR
					perr++;
					nextline=tonext;
				}
			}
			i=SPI_talk(READ,RFM23_26_Received_Signal_Strength_Indicator,0);
			DBGuld(" Send ",psent," packets.");
			DBGuld(" Lost ",perr," packets.");
			DBGuld(" RSSI ",i,"     \r");
//			DBGstr(nextline);
		}else{
			//			SPI_talk(WRITE,RFM23_3E_Packet_Length,0);
			SPI_talk(WRITE,RFM23_7E_RX_FIFO_Control,21);
			RFM23_clear_rx();
			RFM23_to_RX();
			RFM23_set_RXINT();
			RFM23_clear_intterrupt();
			LED_OFF;
//			while (!NIRQ_stat());
			while (NIRQ_stat());
			LED_ON;
//			rndv=SPI_talk(READ,RFM23_4B_Received_Packet_Length,0);
//			DBGuld("COUNT >> ",rndv," ; ");
			for (i=0;i<21;i++) {
				if (i>4) darr[i-5]=RFM23_pop(); else RFM23_pop();
			}
			rndv=SPI_talk(READ,RFM23_26_Received_Signal_Strength_Indicator,0);
			DBGuld("RSSI >> ",rndv,"\r\n");

			RFM23_clear_tx();
			SPI_talk(WRITE,RFM23_3E_Packet_Length,16);
			for (i=0;i<16;i++) RFM23_push(darr[i]);
			RFM23_set_TXINT();
			RFM23_clear_intterrupt();
			RFM23_to_TX();
			while (NIRQ_stat());
			RFM23_to_READY();
		}
	}
	return 0;
}

void HW_init(){
	GPIO_InitTypeDef gpio_init_stuct;
	USART_InitTypeDef usart_init_struct;
	USART_ClockInitTypeDef usartck_init_struct;
	DMA_InitTypeDef dma_init_struct;
	SPI_InitTypeDef spi_init_struct;
	TIM_TimeBaseInitTypeDef time_base_init_struct;
	NVIC_InitTypeDef NVIC_InitStructure;

	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
	RCC_APB2PeriphClockCmd(
			RCC_APB2Periph_AFIO|
			RCC_APB2Periph_GPIOA|
			RCC_APB2Periph_GPIOB|
			RCC_APB2Periph_USART1|
			RCC_APB2Periph_SPI1
			,ENABLE);
	RCC_APB1PeriphClockCmd(
			RCC_APB1Periph_USART2|
			RCC_APB1Periph_TIM4
			,ENABLE);

	/*Светодиод*/
	gpio_init_stuct.GPIO_Mode=GPIO_Mode_Out_OD;
	gpio_init_stuct.GPIO_Pin=GPIO_Pin_8;
	gpio_init_stuct.GPIO_Speed=GPIO_Speed_10MHz;
	GPIO_Init(GPIOA,&gpio_init_stuct);

	/*USART TX*/
	gpio_init_stuct.GPIO_Mode=GPIO_Mode_AF_PP;
	gpio_init_stuct.GPIO_Pin=GPIO_Pin_2;
	gpio_init_stuct.GPIO_Speed=GPIO_Speed_10MHz;
	GPIO_Init(GPIOA,&gpio_init_stuct);

	/*USART RX*/
	gpio_init_stuct.GPIO_Mode=GPIO_Mode_IN_FLOATING;
	gpio_init_stuct.GPIO_Pin=GPIO_Pin_3;
	gpio_init_stuct.GPIO_Speed=GPIO_Speed_10MHz;
	GPIO_Init(GPIOA,&gpio_init_stuct);

	/*SPI: CLK MOSI NSS */
	gpio_init_stuct.GPIO_Mode=GPIO_Mode_AF_PP;
	gpio_init_stuct.GPIO_Pin=GPIO_Pin_5|GPIO_Pin_7;
	gpio_init_stuct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&gpio_init_stuct);

	GPIO_SetBits(GPIOA,GPIO_Pin_4);
	gpio_init_stuct.GPIO_Mode=GPIO_Mode_Out_PP;
	gpio_init_stuct.GPIO_Pin=GPIO_Pin_4;
	gpio_init_stuct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&gpio_init_stuct);

	/*SPI MISO*/
	gpio_init_stuct.GPIO_Mode=GPIO_Mode_IPU;
	gpio_init_stuct.GPIO_Pin=GPIO_Pin_6;
	gpio_init_stuct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&gpio_init_stuct);

	/*SPI nIRQ*/
	gpio_init_stuct.GPIO_Mode=GPIO_Mode_IPU;
	gpio_init_stuct.GPIO_Pin=GPIO_Pin_0;
	gpio_init_stuct.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&gpio_init_stuct);

	/*USART*/
	//	USART_StructInit(&usart_init_struct);
	usart_init_struct.USART_BaudRate=115200UL;
	usart_init_struct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
	usart_init_struct.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;
	usart_init_struct.USART_Parity=USART_Parity_No;
	usart_init_struct.USART_StopBits=USART_StopBits_1;
	usart_init_struct.USART_WordLength=USART_WordLength_8b;
	USART_Init(USART2,&usart_init_struct);
	USART_ClockStructInit(&usartck_init_struct);
	USART_ClockInit(USART2,&usartck_init_struct);


	/*DMA-USART*/
	dma_init_struct.DMA_MemoryBaseAddr=(uint32_t)USART_TX_BUFF;
	dma_init_struct.DMA_MemoryDataSize=DMA_MemoryDataSize_Byte;
	dma_init_struct.DMA_MemoryInc=DMA_MemoryInc_Enable;
	dma_init_struct.DMA_Mode=DMA_Mode_Normal;
	dma_init_struct.DMA_BufferSize=0;
	dma_init_struct.DMA_DIR=DMA_DIR_PeripheralDST;
	dma_init_struct.DMA_M2M=DMA_M2M_Disable;
	dma_init_struct.DMA_Priority=DMA_Priority_High;
	dma_init_struct.DMA_PeripheralBaseAddr=USART2_BASE+0x04;
	dma_init_struct.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte;
	dma_init_struct.DMA_PeripheralInc=DMA_PeripheralInc_Disable;
	DMA_Init(USART2TXDMA,&dma_init_struct);
	DMA_ClearFlag(USART2TCFLAG);
	USART_DMACmd(USART2,USART_DMAReq_Tx,ENABLE);
	//	DMA_Cmd(DMA1_Channel7,ENABLE);
	USART_Cmd(USART2,ENABLE);

	/*SPI*/
	spi_init_struct.SPI_BaudRatePrescaler=SPI_BaudRatePrescaler_16;
	spi_init_struct.SPI_CPHA=SPI_CPHA_1Edge;
	spi_init_struct.SPI_CPOL=SPI_CPOL_Low;
	spi_init_struct.SPI_CRCPolynomial=7;
	spi_init_struct.SPI_DataSize=SPI_DataSize_16b;
	spi_init_struct.SPI_Direction=SPI_Direction_2Lines_FullDuplex;
	spi_init_struct.SPI_FirstBit=SPI_FirstBit_MSB;
	spi_init_struct.SPI_Mode=SPI_Mode_Master;
	spi_init_struct.SPI_NSS=SPI_NSS_Soft;
	SPI_Init(SPI1,&spi_init_struct);
	//	SPI_DataSizeConfig(SPI1,SPI_DataSize_16b);
	//	SPI_SSOutputCmd(SPI1,ENABLE);
	SPI_Cmd(SPI1,ENABLE);

	/*1 sec timer*/
	NVIC_SetVectorTable(NVIC_VectTab_FLASH,0);
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);

	NVIC_InitStructure.NVIC_IRQChannel=TIM4_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority=15;
	NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
	NVIC_Init(&NVIC_InitStructure);

	time_base_init_struct.TIM_ClockDivision=TIM_CKD_DIV1;
	time_base_init_struct.TIM_CounterMode=TIM_CounterMode_Up;
	time_base_init_struct.TIM_Period=36000;
	time_base_init_struct.TIM_Prescaler=1000;
	time_base_init_struct.TIM_RepetitionCounter=0;
	TIM_TimeBaseInit(TIM4,&time_base_init_struct);
	TIM_ARRPreloadConfig(TIM4,ENABLE);
	TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);
//	TIM_Cmd(TIM4,ENABLE);

}

void TIM4_IRQHandler(void) {
	TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
	timeout_flag=1;
	TIM_Cmd(TIM4,DISABLE);
}

